/**
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef PLUGINS_ECMASCRIPT_COMPILER_INLINE_INTRINSICS_ECMASCRIPT_INL_H
#define PLUGINS_ECMASCRIPT_COMPILER_INLINE_INTRINSICS_ECMASCRIPT_INL_H

static constexpr size_t GetLdStLexVarDynLevelThreshold()
{
    constexpr size_t MAX_LEVEL = 2U;
    return MAX_LEVEL;
}

private:
bool InlineLdTrue(IntrinsicInst *intrinsic);
bool InlineLdFalse(IntrinsicInst *intrinsic);
bool InlineLdHole(IntrinsicInst *intrinsic);
bool InlineLdNull(IntrinsicInst *intrinsic);
bool InlineLdUndefined(IntrinsicInst *intrinsic);
bool InlineLdInfinity(IntrinsicInst *intrinsic);
bool InlineLdNan(IntrinsicInst *intrinsic);
bool InlineLdObjByName(IntrinsicInst *intrinsic);
bool InlineStObjByName(IntrinsicInst *intrinsic);
bool InlineLdObjByValue(IntrinsicInst *intrinsic);
bool InlineStObjByValue(IntrinsicInst *intrinsic);
bool InlineResolveAllocResult(IntrinsicInst *intrinsic);
bool InlineTypeOf(IntrinsicInst *intrinsic);

#include "plugins/ecmascript/runtime/builtins/generated/builtins_inline_intrinsics_decls_gen.inl"

template <bool IS_LOAD>
bool InlineObjByName(IntrinsicInst *intrinsic);
template <bool IS_LOAD>
bool InlineObjByValue(IntrinsicInst *intrinsic);

template <bool IS_LOAD>
void InlineObjByValueWithKey(IntrinsicInst *intrinsic);
template <bool IS_LOAD>
void InlineObjByValueFromElements(IntrinsicInst *intrinsic);

template <bool IS_LOAD>
void InlineObjByNameMonomorphic(IntrinsicInst *intrinsic, Inst *getClsInst, Inst *objInst);
template <bool IS_LOAD>
void InlineObjByNamePolymorphic(IntrinsicInst *intrinsic, Inst *getClsInst, Inst *objInst);

bool GetICForMemNamedAccess(IntrinsicInst *intrinsic);
bool GetICForMemValueAccess(IntrinsicInst *intrinsic);
template <bool BY_NAME>
Inst *InsertCheckAndCastInstructions(IntrinsicInst *intrinsic);

void CreateCompareClass(uint32_t pc, Inst *getClsInst, RuntimeInterface::ClassPtr receiver, BasicBlock *loadBb);
Inst *CreateCompareClassWithDeopt(uint32_t pc, Inst *getClsInst, RuntimeInterface::ClassPtr receiver, Inst *saveState);

profiling::AnyInputType GetAllowedTypeForInput(IntrinsicInst *intrinsic, size_t index);
bool InlineStrictCompareDifferentTypes(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineStrictEqDyn(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineStrictNotEqDyn(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineCompareWithNull(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineEqDyn(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineNotEqDyn(IntrinsicInst *intrinsic, AnyBaseType type1, AnyBaseType type2);
bool InlineToNumber(IntrinsicInst *intrinsic, AnyBaseType type1);
Inst *GetParentLexEnv(InstAppender *appender, Inst *currentLexEnv, uint32_t level, uint32_t pc);
bool InlineLdLexDyn(IntrinsicInst *intrinsic);
bool InlineStLexDyn(IntrinsicInst *intrinsic);
bool InlineLdLexVarDyn(IntrinsicInst *intrinsic);
bool InlineLdlexenvDyn(IntrinsicInst *intrinsic);
bool InlineStLexVarDyn(IntrinsicInst *intrinsic);
bool InlinePopLexenvDyn(IntrinsicInst *intrinsic);

bool InlineTryLdGlobalByName(IntrinsicInst *inst);
template <bool NEED_GUARD>
void InlineTryLdGlobalField(IntrinsicInst *inst, uint32_t typeId, uintptr_t address);

#endif  // PLUGINS_ECMASCRIPT_COMPILER_INLINE_INTRINSICS_ECMASCRIPT_INL_H
